package pay

import java.math.BigDecimal
import java.text.SimpleDateFormat
import java.util.{Calendar, Date}

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.SerializerFeature
import com.alipay.api.AlipayApiException
import com.alipay.api.domain.{AlipayTradeAppPayModel, AlipayTradeCloseModel}
import com.alipay.api.request.{AlipayTradeAppPayRequest, AlipayTradeCloseRequest}
import dto.req.{CloseOrderReqDTO, PayOrderReqDTO}
import dto.resp.{CloseOrderRespDTO, PayOrderRespDTO}
import enums.{PayChannelEnum, PayEnum, ThirdSystemErrorEnum}
import exception.CommonException
import factory.ActionFactory
import org.springframework.beans.BeanUtils
import org.springframework.beans.factory.InitializingBean
import org.springframework.stereotype.Service

@Service
class AliPayAction extends BasePayAction with InitializingBean{

  override def getPayChannel: Integer = PayChannelEnum.ALI_PAY.getId

  @throws[Exception]
  override def buildOrder[T <: PayOrderReqDTO, R >: PayOrderRespDTO](req: T): R = {
    val payRequest = new AlipayTradeAppPayRequest
    val model = new AlipayTradeAppPayModel
    //自己实现生成orderNO的方法
    val payOrderNo = ""
    model.setBody(req.getGoodsName)
    model.setSubject(req.getGoodsName)
    model.setOutTradeNo(payOrderNo)
    //订单超时时间 10分钟，逾期将关闭订单
    val calendar = Calendar.getInstance
    calendar.add(Calendar.MINUTE, 10)
    model.setTimeExpire(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(calendar.getTime))
    model.setTimeoutExpress("11m")
    var bigDecimal = new BigDecimal(String.valueOf(req.getPayAmount))
    bigDecimal = bigDecimal.divide(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP)
    model.setTotalAmount(bigDecimal.toPlainString)
    model.setProductCode(aliPayProperties.productCode)
    //val params = new JSONObject()
    //params.put("biz_code", req.getBizCode)
    //model.setPassbackParams(params.toJSONString)
    payRequest.setBizModel(model)
    payRequest.setNotifyUrl(aliPayProperties.getNotifyURL)
    log.info("alipay request params : {}", JSON.toJSONString(payRequest, SerializerFeature.PrettyFormat))
    val payResponse = alipayClient.sdkExecute(payRequest)
    log.info("alipay response result : {}", JSON.toJSONString(payResponse, SerializerFeature.PrettyFormat))
    if (!payResponse.isSuccess) throw new CommonException(payResponse.getCode, payResponse.getMsg)
    val resp = new PayOrderRespDTO
    BeanUtils.copyProperties(req, resp)
    resp.setPayOrderNo(payOrderNo)
    resp.setOrderBody(payResponse.getBody)
    resp.setCreateTime(new Date)
    resp.setUpdateTime(new Date)
    resp.setExpiredTime(calendar.getTime)
    resp
  }

  @throws[AlipayApiException]
  override def closeOrder[T <: CloseOrderReqDTO, R >: CloseOrderRespDTO](req: T): R = {
    val closeRequest = new AlipayTradeCloseRequest
    val model = new AlipayTradeCloseModel
    model.setOutTradeNo(req.getPayOrderNo)
    //model.setTradeNo(req.getThirdOrderNo());
    closeRequest.setBizModel(model)
    log.info("alipay close request params : {}", JSON.toJSONString(closeRequest, SerializerFeature.PrettyFormat))
    val closeResponse = alipayClient.execute(closeRequest)
    log.info("alipay close response result : {}", JSON.toJSONString(closeResponse, SerializerFeature.PrettyFormat))
    val resp = new CloseOrderRespDTO
    BeanUtils.copyProperties(req, resp)
    resp.setBizCode(req.getBizCode)
    if (!closeResponse.isSuccess) {
      resp.setOrderStatusCode(ThirdSystemErrorEnum.getErrorEnum(closeResponse.getCode).getCode)
      resp.setOrderStatusMessage(ThirdSystemErrorEnum.getErrorEnum(closeResponse.getMsg).getMessage)
    }
    else {
      resp.setOrderStatusCode(PayEnum.PayTradeStatusEnum.getByThirdCode(closeResponse.getSubCode, req.getPayChannel).getCode)
      resp.setOrderStatusMessage(PayEnum.PayTradeStatusEnum.getByThirdCode(closeResponse.getSubCode, req.getPayChannel).getDesc)
    }
    resp
  }

  override def afterPropertiesSet(): Unit = ActionFactory.setPayAction(getPayChannel, this)
}
